<template>
  <div class="page-box">
    <div class="head">
      <span class="title">商品分类管理</span>
      <div class="toolbar">
        <el-button type="primary" icon="Plus" @click="addOrModify(null, 1)">添加</el-button>
      </div>
    </div>

    <div class="table">
      <el-table
          ref="treeTable"
          lazy
          stripe
          row-key="id"
          :data="listData"
          :load="loadCategoryData"
          v-loading="loading"
          :tree-props="{ hasChildren: 'hasChildren' }"
      >
        <el-table-column prop="categoryName" label="分类名称" />
        <el-table-column prop="categorySort" label="排序" />
        <el-table-column prop="created" label="创建时间" align="right" width="138" />
        <el-table-column label="操作" fixed="right" width="200" align="center" #default="{ row }">
          <el-button type="primary" icon="Plus" @click="addOrModify(row, 2)" />
          <el-button type="primary" icon="Edit" @click="addOrModify(row, 3)" />
          <el-button type="danger" icon="Delete" @click="del(row)" />
        </el-table-column>
      </el-table>
    </div>

    <el-drawer
        size="36%"
        :title="addOrModifyDrawerTitle"
        v-model="isShowAddOrModifyDrawer"
        direction="rtl"
        :before-close="addOrModifyDrawerClose"
        @opened="addOrModifyDrawerOpened(addOrModifyFormRef)"
    >
      <div class="form-content">
        <el-form ref="addOrModifyFormRef" label-width="70px" :model="addOrModifyModel" :rules="addOrModifyRules">
          <el-form-item label="父分类" v-show="isShowParentCategory" prop="parentId">
            <el-input v-model="parentCategoryName" disabled />
          </el-form-item>
          <el-form-item label="名称" prop="categoryName">
            <el-input v-model="addOrModifyModel.categoryName" placeholder="分类名称" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="排序" prop="categorySort">
            <el-input v-model="addOrModifyModel.categorySort" placeholder="分类排序" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="Logo" prop="categoryLogo">
            <el-input v-model="addOrModifyModel.categoryLogo" placeholder="上传或者在这里填写Logo地址" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="Logo" prop="categoryLogo">
            <el-upload
                :data="{usage: 'goods-category'}"
                class="uploader"
                :headers="headers"
                :action="uploadUrl"
                :on-success="uploadSuccessHandle"
                :show-file-list="false"
            >
              <el-image v-if="imgUrl" :src="imgUrl" fit="scale-down" style="width: 160px;height: 140px;"></el-image>
              <el-icon v-else class="uploader-icon"><Plus /></el-icon>
            </el-upload>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :loading="loading" @click="doAddOrModify">
              {{ loading ? '正在提交 ...' : '提交' }}
            </el-button>
            <el-button @click="addOrModifyDrawerClose">取消</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-drawer>

    <el-dialog
        v-model="isShowDelDialog"
        title="提示"
        width="30%"
        :before-close="delDialogClose"
    >
      <span>确定要删除吗？</span>
      <template #footer>
        <span>
          <el-button @click="delDialogClose">取消</el-button>
          <el-button type="primary" :loading="loading" @click="doDel">
            {{ loading ? '正在删除 ...' : '确定' }}
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useApp } from '@/pinia/modules/app'
import { ElMessage } from "element-plus"
import { GetListData, AddData, ModifyData, DeleteData } from '@/api/goods/category'
import { uploadPictureUrl, RemoveFile } from '@/api/upload'

const loading = ref(false)
const fileServerUrl = ref(import.meta.env.VITE_FILE_SERVER_URL)

/* 列表开始 */
const treeTable = ref()
const listData = ref([])
const editDataMap = ref(new Map())

const loadCategoryData = async (row, treeNode, resolve) => {
  if (loading.value) {
    return
  }
  editDataMap.value.set(row.id, { row, treeNode, resolve })
  loading.value = true
  const { code, message, data } = await GetListData(row.id)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  data.map(item => {
    if (item.categoryLogo && item.categoryLogo.length > 0 && !item.categoryLogo.startsWith('http:') && !item.categoryLogo.startsWith('https:')) {
      item.categoryLogoUrl = `${fileServerUrl.value}${item.categoryLogo}`
    } else {
      item.categoryLogoUrl = item.categoryLogo
    }
  })
  resolve(data)
}

const fetchListData = async () => {
  if (loading.value) {
    return
  }
  loading.value = true
  const { code, message, data } = await GetListData(0)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  data.map(item => {
    if (item.categoryLogo && item.categoryLogo.length > 0 && !item.categoryLogo.startsWith('http')) {
      item.categoryLogoUrl = `${fileServerUrl.value}${item.categoryLogo}`
    } else {
      item.categoryLogoUrl = item.categoryLogo
    }
  })
  listData.value = data
}

onMounted(() => {
  fetchListData()
})
/* 列表结束 */

/* 上传头像开始 */
const { authorization } = useApp()
const headers = ref({ token: authorization.token })
const imgUrl = ref()
const uploadUrl = ref(uploadPictureUrl)

const uploadSuccessHandle = res => {
  const { code, message, data } = res
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  const fileName = addOrModifyModel.value.categoryLogo
  if (fileName.length > 0 && !fileName.startsWith('http:') && !fileName.startsWith('https:')) {
    RemoveFile({
      fileNames: [fileName]
    })
  }
  addOrModifyModel.value.categoryLogo = data.url
  imgUrl.value = `${fileServerUrl.value}${data.url}`
}
/* 上传头像结束 */

/* 添加修改开始 */
const operation = ref(1)
const currentRow = ref()
const parentCategoryName = ref('')
const isShowParentCategory = ref(false)
const addOrModifyFormRef = ref()
const addOrModifyDrawerTitle = ref('')
const isShowAddOrModifyDrawer = ref(false)

const addOrModifyData = {
  parentId: 0,
  categoryName: '',
  categoryLogo: null,
  categorySort: 1,
}
const addOrModifyModel = ref({ ...addOrModifyData })

const addOrModifyRules = ref({
  parentId: [{ required: true, message: '请选择上级分类', trigger: 'blur' }],
  categoryName: [{ required: true, message: '请输入分类名称', trigger: 'blur' }],
})

const addOrModify = (row, t) => {
  operation.value = t
  if (row == null) {
    addOrModifyModel.value.parentId = 0
    isShowParentCategory.value = false
    addOrModifyDrawerTitle.value = '添加顶级分类'
  } else {
    currentRow.value = row
    if (t === 2) {
      addOrModifyModel.value.parentId = row.id
      parentCategoryName.value = row.categoryName
      isShowParentCategory.value = true
      addOrModifyDrawerTitle.value = '添加子分类'
    } else {
      isShowParentCategory.value = false
      addOrModifyDrawerTitle.value = '编辑分类'
      imgUrl.value = row.categoryLogoUrl
      addOrModifyModel.value = { ...row }
      addOrModifyModel.value.parentId = row.parentId
      delete addOrModifyModel.value.created
      delete addOrModifyModel.value.updated
    }
  }
  isShowAddOrModifyDrawer.value = true
}

const doAddOrModify = () => {
  if (loading.value) {
    return
  }
  addOrModifyFormRef.value.validate(async valid => {
    if (!valid) {
      return
    }
    loading.value = true
    let code, message
    if (addOrModifyModel.value.id && addOrModifyModel.value.id > 0) {
      const result = await ModifyData(addOrModifyModel.value)
      code = result.code
      message = result.message
    } else {
      const result = await AddData(addOrModifyModel.value)
      code = result.code
      message = result.message
    }
    loading.value = false
    if (code !== 200) {
      ElMessage.error(message)
      return
    }
    isShowAddOrModifyDrawer.value = false
    resetAddOrModify()

    if (operation.value === 1) { // 如果是添加顶级分类
      await fetchListData()
    } else if (operation.value === 2) { // 如果是添加子分类
      currentRow.value.hasChildren = true
      const treeData = treeTable.value.store.states.treeData.value
      if (treeData[currentRow.value.id]) {
        treeData[currentRow.value.id].loading = true
        treeData[currentRow.value.id].expanded = false
        treeData[currentRow.value.id].loaded = false
      } else {
        treeData[currentRow.value.id] = {
          loaded: false
        }
      }
      treeTable.value.store.loadOrToggle(currentRow.value)
    } else { // 如果是编辑
      if (currentRow.value.parentId > 0) {
        const  { row, treeNode, resolve } = editDataMap.value.get(currentRow.value.parentId)
        await loadCategoryData(row, treeNode, resolve)
      } else {
        await fetchListData()
      }
    }

    ElMessage.success(message)
  })
}

const addOrModifyDrawerOpened = formEl => {
  formEl.clearValidate()
}

const resetAddOrModify = () => {
  imgUrl.value = ''
  isShowParentCategory.value = false
  addOrModifyFormRef.value.resetFields()
  addOrModifyModel.value = { ...addOrModifyData }
  addOrModifyModel.value.parentId = '0'
  loading.value = false
}

const addOrModifyDrawerClose = () => {
  if (loading.value) {
    return
  }
  resetAddOrModify()
  isShowAddOrModifyDrawer.value = false
}
/* 添加修改结束 */

/* 删除开始 */
const delRow = ref({})
const isShowDelDialog = ref(false)
const delModel = ref({ ids: [] })

const del = row => {
  delRow.value = row
  delModel.value.ids.push(row.id)
  isShowDelDialog.value = true
}

const doDel = async () => {
  if (loading.value) {
    return
  }
  loading.value = true
  const { code, message } = await DeleteData(delModel.value)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  treeTable.value.store.states.lazyTreeNodeMap.value[delRow.value.parentId] = []
  isShowDelDialog.value = false
  resetDel()
  if (delRow.value.parentId > 0) {
    const  { row, treeNode, resolve } = editDataMap.value.get(delRow.value.parentId)
    await loadCategoryData(row, treeNode, resolve)
  } else {
    await fetchListData()
  }
  ElMessage.success(message)
}

const resetDel = () => {
  delModel.value.ids = []
  loading.value = false
}

const delDialogClose = () => {
  if (loading.value) {
    return
  }
  resetDel()
  isShowDelDialog.value = false
}
/* 删除结束 */
</script>

<style scoped lang="scss">
.page-box {
  width: 100%;
  box-sizing: border-box;
  .head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 20px 0;
    background: #fff;
    .title {
      font-size: 16px;
    }
    .toolbar {
      padding: {
        right: 20px;
      }
    }
  }
  .table {
    padding: 20px;
    background: #fff;
    /* table表格中的图片样式开始 */
    :deep(.image-slot) {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 80px;
      height: 60px;
      background: var(--el-fill-color-light);
      color: var(--el-text-color-secondary);
      font-size: 30px;
    }
    /* table表格中的图片样式结束 */
  }
  .form-content {
    /* 上传组件的样式开始 */
    .uploader {
      :deep(.el-upload) {
        border: 1px dashed var(--el-border-color);
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        transition: var(--el-transition-duration-fast);
      }
      :deep(.el-upload:hover) {
        border-color: var(--el-color-primary);
      }
      :deep(.uploader-icon) {
        font-size: 28px;
        color: #8c939d;
        width: 160px;
        height: 140px;
        text-align: center;
      }
    }
    /* 上传组件的样式结束 */
  }
}
</style>